import { _decorator, Component, Label, Color, Node, Widget } from 'cc';
import { GlobalEventBus } from '../core/EventBus';
import { track } from '../telemetry/Track';

const { ccclass, property } = _decorator;

interface AmmoChangedPayload {
  weaponId: string;
  mag: number;
  reserve: number;
}

@ccclass('HUDController')
export class HUDController extends Component {
  @property(Label)
  public weaponLabel: Label | null = null;

  @property(Label)
  public magazineLabel: Label | null = null;

  @property(Label)
  public reserveLabel: Label | null = null;

  @property(Label)
  public toastLabel: Label | null = null;

  @property(Label)
  public reloadStatusLabel: Label | null = null;

  @property(Label)
  public extractIconLabel: Label | null = null;

  private unsubscribeAmmoChanged: (() => void) | null = null;
  private unsubscribeAmmoOut: (() => void) | null = null;
  private unsubscribeReloadBegin: (() => void) | null = null;
  private unsubscribeReloadEnd: (() => void) | null = null;
  private unsubscribeToast: (() => void) | null = null;
  private reloadCountdown = 0;
  private extractWorldX = 0;
  private extractWorldY = 0;
  private unsubscribeExtract: (() => void) | null = null;

  onEnable() {
    this.unsubscribeAmmoChanged = GlobalEventBus.on('ammo/changed', (payload) => {
      this.updateAmmo(payload);
    });
    this.unsubscribeAmmoOut = GlobalEventBus.on('ammo/out', (payload) => {
      track('ammo_out', payload);
      this.showToast('弹药不足，尝试换弹');
    });
    this.unsubscribeReloadBegin = GlobalEventBus.on('reload/begin', (payload) => {
      this.reloadCountdown = payload.t ?? 0;
      if (this.reloadStatusLabel) {
        this.reloadStatusLabel.string = `Reloading...(${this.reloadCountdown.toFixed(1)}s)`;
      }
      this.unschedule(this._tickReload);
      this.schedule(this._tickReload, 0.1);
    });
    this.unsubscribeReloadEnd = GlobalEventBus.on('reload/end', () => {
      this.unschedule(this._tickReload);
      if (this.reloadStatusLabel) {
        this.reloadStatusLabel.string = '';
      }
      this.showToast('换弹完成');
    });
    this.unsubscribeToast = GlobalEventBus.on('hud/toast', (payload) => {
      this.showToast(payload.text, payload.ms);
    });
    this.unsubscribeExtract = GlobalEventBus.on('extract/available', (payload) => {
      this.extractWorldX = (payload.at as any).x ?? 0;
      this.extractWorldY = (payload.at as any).y ?? 0;
      this.showToast('可撤离点已出现', 1500);
      // Create a simple icon at top-right
      if (!this.extractIconLabel) {
        const n = new Node('ExtractIcon');
        const lab = n.addComponent(Label);
        lab.string = '🔰';
        lab.color = new Color(0, 255, 0, 255);
        const wg = n.addComponent(Widget);
        wg.isAlignTop = true; wg.isAlignRight = true; wg.top = 8; wg.right = 8;
        this.node.addChild(n);
        this.extractIconLabel = lab;
      } else {
        this.extractIconLabel.string = '🔰';
      }
    });
  }

  onDisable() {
    this.unsubscribeAmmoChanged?.();
    this.unsubscribeAmmoChanged = null;
    this.unsubscribeAmmoOut?.();
    this.unsubscribeAmmoOut = null;
    this.unsubscribeReloadBegin?.();
    this.unsubscribeReloadBegin = null;
    this.unsubscribeReloadEnd?.();
    this.unsubscribeReloadEnd = null;
    this.unsubscribeToast?.();
    this.unsubscribeToast = null;
    this.unsubscribeExtract?.();
    this.unsubscribeExtract = null;
    this.unscheduleAllCallbacks();
  }

  private updateAmmo(payload: AmmoChangedPayload) {
    if (this.weaponLabel) {
      this.weaponLabel.string = `Weapon: ${payload.weaponId}`;
    }
    if (this.magazineLabel) {
      this.magazineLabel.string = `Mag: ${payload.mag}`;
    }
    if (this.reserveLabel) {
      this.reserveLabel.string = `Reserve: ${payload.reserve}`;
    }
  }

  private showToast(message: string, ms = 400) {
    if (!this.toastLabel) {
      return;
    }
    this.toastLabel.string = message;
    this.toastLabel.color = Color.WHITE;
    this.unschedule(this.clearToast);
    this.scheduleOnce(this.clearToast, ms / 1000);
  }

  private clearToast = () => {
    if (!this.toastLabel) {
      return;
    }
    this.toastLabel.string = '';
  };

  private _tickReload = () => {
    this.reloadCountdown = Math.max(0, this.reloadCountdown - 0.1);
    if (this.reloadStatusLabel) {
      this.reloadStatusLabel.string = `Reloading...(${this.reloadCountdown.toFixed(1)}s)`;
    }
  };

  public setWeapon(weaponId: string) {
    if (this.weaponLabel) {
      this.weaponLabel.string = `Weapon: ${weaponId}`;
    }
  }
}
